package cn.hesion.dataStructures.Josepfu;

public class CircleLinkedList {
    //创建first节点
    private Boy first = new Boy(-1);

    //添加小孩节点，构建环形链表
    public void addBoy(int num) {
        if (num < 2) {
            System.out.println("nums的不正确");
            return;
        }
        Boy curBoy = null;
        for (int i = 1; i <= num; i++) {
            //根据编号创建小孩节点
            Boy boy = new Boy(i);
            // 如果是第一个小孩
            if (i == 1) {
                first = boy;
                first.setNext(first);
                curBoy = first;
            } else {
                curBoy.setNext(boy);
                boy.setNext(first);
                curBoy = boy;
            }
        }

    }

    public void listCircle() {
        if (first.getNext() == null) {
            System.out.println("环形链表为空");
            return;
        }

        Boy curBoy = first;
        while (true){
            System.out.printf("小孩的编号 %d\n",curBoy.getNo());
            if(curBoy.getNext() == first){
                break;
            }
            curBoy=curBoy.getNext();
        }
    }
    public void countBoy(int startNo,int countNum,int nums){
        //先对传入的参数进行校验
        if(first==null||countNum > nums){
            System.out.println("参数有误");
            return;
        }

        //创建一个辅助节点，完成小孩的出圈
        Boy helper = first;
        //辅助节点最开始应当移动到环形队列的最后一个元素
        while(true){
            if(helper.getNext()==null){
                break;
            }
            helper = helper.getNext();
        }

        //小孩报数前，先让first和helper移动k-1次 k就是用户输入的startNo
        for (int i = 0; i < startNo - 1; i++) {
            first=first.getNext();
            helper=helper.getNext();
        }

        //当小孩报数时，让first和helper同时移动m-1次,然后出圈
        //循环开始报数，直到圈中只有一个节点
        while (true){
            if(helper==first){
                break;
            }

            //让first和helper同时移动countNum-1次
            for (int j = 0; j < countNum - 1; j++) {
                first=first.getNext();
                helper=helper.getNext();
            }
            //这时first指向的节点，就是要出圈的小孩节点
            System.out.printf("小孩%d出圈\n", first.getNo());
            //这个时候将first所指向的小孩的节点出圈
            first=first.getNext();
            helper.setNext(first);
        }



    }
}
